package top.v5it.japi.plus.common.func;

import java.util.Objects;

/**
 * 自定义函数，多个不定输入参数，1个输出
 *
 * @author zhanpu
 * @date 2022/5/20
 */
@FunctionalInterface
public interface Func<T, R, E extends Throwable> {

    /**
     * 不定输入参数函数，1个输出
     *
     * @param t 不定参数
     * @return R 返回值
     * @throws E 可能出现的异常
     */
    @SuppressWarnings("unchecked")
    R apply(T... t) throws E;


    /**
     * 先调用本函数，再基于本函数结果调用输入函数
     *
     * @param after 输入函数
     * @param <V>   输出类型
     * @return 返回V
     */
    default <V> Func<T, V, E> andThen(Func1<? super R, ? extends V, ? extends E> after) {
        Objects.requireNonNull(after);

        return (t) -> {
            try {
                return after.apply(apply(t));
            } catch (Throwable e) {
                throw new FuncException(e);
            }
        };
    }

    /**
     * 基于本函数返回{@link FuncException}
     *
     * @param t 不定参数
     * @return R 返回值
     */
    @SuppressWarnings("unchecked")
    default R applyWithFuncException(T... t) {
        try {
            return apply(t);
        } catch (Throwable e) {
            throw new FuncException(e);
        }
    }
}
